can help make your program more bullet-proof, but sometimes
it's too annoying for quick throw-away programs.
<p><h3>Awk Traps</h3>
Accustomed <B>awk</B> users should take special note of the following:
<p>
<dl>
<dt><B>*</B>
<dd>
The English module, loaded via
<p></dd>
<pre>
use English;
</pre>
allows you to refer to special variables (like $RS) as
though they were in <B>awk</B>; see
<A HREF="perlvar.html">
the perlvar manpage</A>
for details.
<p><dt><B>*</B>
<dd>
Semicolons are required after all simple statements in Perl (except
at the end of a block). Newline is not a statement delimiter.
<p></dd>
<dt><B>*</B>
<dd>
Curly brackets are required on <B>if</B>s and <B>while</B>s.
<p></dd>
<dt><B>*</B>
<dd>
Variables begin with "$" or "@" in Perl.
<p></dd>
<dt><B>*</B>
<dd>
Arrays index from 0. Likewise string positions in substr() and
index().
<p></dd>
<dt><B>*</B>
<dd>
You have to decide whether your array has numeric or string indices.
<p></dd>
<dt><B>*</B>
<dd>
Associative array values do not spring into existence upon mere
reference.
<p></dd>
<dt><B>*</B>
<dd>
You have to decide whether you want to use string or numeric
comparisons.
<p></dd>
<dt><B>*</B>
<dd>
Reading an input line does not split it for you. You get to split it
yourself to an array. And split() operator has different
arguments.
<p></dd>
<dt><B>*</B>
<dd>
The current input line is normally in $_, not $0. It generally does
not have the newline stripped. ($0 is the name of the program
executed.) See
<A HREF="perlvar.html">
the perlvar manpage</A>
.
<p></dd>
<dt><B>*</B>
<dd>
$<<I>digit</I>> does not refer to fields--it refers to substrings matched by
the last match pattern.
<p></dd>
<dt><B>*</B>
<dd>
The print() statement does not add field and record separators unless
you set
<A HREF="perlvar.html#perlvar_397">$,</A>
and
<A HREF="perlvar.html#perlvar_386">$.</A>
. You can set $OFS and $ORS if you're using
the English module.
<p></dd>
<dt><B>*</B>
<dd>
You must open your files before you print to them.
<p></dd>
<dt><B>*</B>
<dd>
The range operator is "..", not comma. The comma operator works as in
C.
<p></dd>
<dt><B>*</B>
<dd>
The match operator is "=~", not "~". ("~" is the one's complement
operator, as in C.)
<p></dd>
<dt><B>*</B>
<dd>
The exponentiation operator is "**", not "^". "^" is the XOR
operator, as in C. (You know, one could get the feeling that <B>awk</B> is
basically incompatible with C.)
<p></dd>
<dt><B>*</B>
<dd>
The concatenation operator is ".", not the null string. (Using the
null string would render <B>/pat/ /pat/</B> unparsable, since the third slash
would be interpreted as a division operator--the tokener is in fact
slightly context sensitive for operators like "/", "?", and ">".
And in fact, "." itself can be the beginning of a number.)
<p></dd>
<dt><B>*</B>
<dd>
The
<A HREF="perlfunc.html#perlfunc_179">next</A>
,
<A HREF="perlfunc.html#perlfunc_104">exit</A>
, and <B>continue</B> keywords work differently.
<p></dd>
<dt><B>*</B>
<dd>
The following variables work differently:
<p></dd>
<listing>
Awk Perl
ARGC $#ARGV or scalar @ARGV
ARGV[0] $0
FILENAME $ARGV
FNR $. - something
FS (whatever you like)
NF $#Fld, or some such
NR $.
OFMT $#
OFS $,
ORS $\
RLENGTH length($&)
RS $/
RSTART length($`)
SUBSEP $;
</listing>
<dt><B>*</B>
<dd>
You cannot set $RS to a pattern, only a string.
<p></dd>
<dt><B>*</B>
<dd>
When in doubt, run the <B>awk</B> construct through <B>a2p</B> and see what it
gives you.
<p></dd>
</dl>
<h3>C Traps</h3>
Cerebral C programmers should take note of the following:
<p>
<dl>
<dt><B>*</B>
<dd>
Curly brackets are required on <B>if</B>'s and <B>while</B>'s.
<p></dd>
<dt><B>*</B>
<dd>
You must use <B>elsif</B> rather than <B>else if</B>.
<p></dd>
<dt><B>*</B>
<dd>
The <B>break</B> and <B>continue</B> keywords from C become in
Perl
<A HREF="perlfunc.html#perlfunc_161">last</A>
and
<A HREF="perlfunc.html#perlfunc_179">next</A>
, respectively.
Unlike in C, these do <I>NOT</I> work within a <B>do { } while</B> construct.
<p></dd>
<dt><B>*</B>
<dd>
There's no switch statement. (But it's easy to build one on the fly.)
<p></dd>
<dt><B>*</B>
<dd>
Variables begin with "$" or "@" in Perl.
<p></dd>
<dt><B>*</B>
<dd>
printf() does not implement the "*" format for interpolating
field widths, but it's trivial to use interpolation of double-quoted
strings to achieve the same effect.
<p></dd>
<dt><B>*</B>
<dd>
Comments begin with "#", not "/*".
<p></dd>
<dt><B>*</B>
<dd>
You can't take the address of anything, although a similar operator
in Perl 5 is the backslash, which creates a reference.
<p></dd>
<dt><B>*</B>
<dd>
<B>ARGV</B> must be capitalized.
<p></dd>
<dt><B>*</B>
<dd>
System calls such as link(), unlink(), rename(), etc. return nonzero for
success, not 0.
<p></dd>
<dt><B>*</B>
<dd>
Signal handlers deal with signal names, not numbers. Use <B>kill -l</B>
to find their names on your system.
<p></dd>
</dl>
<h3>Sed Traps</h3>
Seasoned <B>sed</B> programmers should take note of the following:
<p>
<dl>
<dt><B>*</B>
<dd>
Backreferences in substitutions use "$" rather than "\".
<p></dd>
<dt><B>*</B>
<dd>
The pattern matching metacharacters "(", ")", and "|" do not have backslashes
in front.
<p></dd>
<dt><B>*</B>
<dd>
The range operator is <B>...</B>, rather than comma.
<p></dd>
</dl>
<h3>Shell Traps</h3>
Sharp shell programmers should take note of the following:
<p>
<dl>
<dt><B>*</B>
<dd>
The backtick operator does variable interpretation without regard to
the presence of single quotes in the command.
<p></dd>
<dt><B>*</B>
<dd>
The backtick operator does no translation of the return value, unlike <B>csh</B>.
<p></dd>
<dt><B>*</B>
<dd>
Shells (especially <B>csh</B>) do several levels of substitution on each
command line. Perl does substitution only in certain constructs
such as double quotes, backticks, angle brackets, and search patterns.
<p></dd>
<dt><B>*</B>
<dd>
Shells interpret scripts a little bit at a time. Perl compiles the
entire program before executing it (except for <B>BEGIN</B> blocks, which
execute at compile time).
<p></dd>
<dt><B>*</B>
<dd>
The arguments are available via @ARGV, not $1, $2, etc.
<p></dd>
<dt><B>*</B>
<dd>
The environment is not automatically made available as separate scalar
variables.
<p></dd>
</dl>
<h3>Perl Traps</h3>
Practicing Perl Programmers should take note of the following:
<p>
<dl>
<dt><B>*</B>
<dd>
Remember that many operations behave differently in a list
context than they do in a scalar one. See
<A HREF="perldata.html">
the perldata manpage</A>
for details.
<p></dd>
<dt><B>*</B>
<dd>
Avoid barewords if you can, especially all lower-case ones.
You can't tell just by looking at it whether a bareword is
a function or a string. By using quotes on strings and
parens on function calls, you won't ever get them confused.
<p></dd>
<dt><B>*</B>
<dd>
You cannot discern from mere inspection which built-ins
are unary operators (like chop() and chdir())
and which are list operators (like print() and unlink()).
(User-defined subroutines can <B>only</B> be list operators, never
unary ones.) See
<A HREF="perlop.html">
the perlop manpage</A>
.
<p></dd>
<dt><B>*</B>
<dd>
People have a hard type remembering that some functions
default to $_, or @ARGV, or whatever, but that others which
you might expect to do not.
<p></dd>
<dt><B>* </B>
<dd>
Remember not to use "<B>=</B>" when you need "<B>=~</B>";
these two constructs are quite different:
<p></dd>
<pre>
$x = /foo/;
$x =~ /foo/;
</pre>
<dt><B>*</B>
<dd>
The <B>do {}</B> construct isn't a real loop that you can use
loop control on.
<p></dd>
<dt><B>*</B>
<dd>
Use my() for local variables whenever you can get away with
it (but see
<A HREF="perlform.html">
the perlform manpage</A>
for where you can't).
Using local() actually gives a local value to a global
variable, which leaves you open to unforeseen side-effects
of dynamic scoping.
<p></dd>
</dl>
<h3>Perl4 Traps</h3>
Penitent Perl 4 Programmers should take note of the following
incompatible changes that occurred between release 4 and release 5:
<p>
<dl>
<dt><B>*</B>
<dd>
<B>@</B> now always interpolates an array in double-quotish strings. Some programs
may now need to use backslash to protect any <B>@</B> that shouldn't interpolate.
<p></dd>
<dt><B>* Barewords that used to look like strings to Perl will now look like subroutine calls if a subroutine by that name is defined before the compiler sees them. For example:</B>
<pre>
sub SeeYa { die "Hasta la vista, baby!" }
$SIG{QUIT} = SeeYa;
</pre>
<dd>
In Perl 4, that set the signal handler; in Perl 5, it actually calls the
function! You may use the
<A HREF="perlrun.html#perlrun_362">-w</A>
switch to find such places.
<p></dd>
<dt><B>*</B>
<dd>
Symbols starting with <B>_</B> are no longer forced into package <B>main</B>, except
for $_ itself (and @_, etc.).
<p></dd>
<dt><B>*</B>
<dd>
<B>s'$lhs'$rhs'</B> now does no interpolation on either side. It used to
interpolate <B>$lhs</B> but not <B>$rhs</B>.
<p></dd>
<dt><B>*</B>
<dd>
The second and third arguments of splice() are now evaluated in scalar
context (as the book says) rather than list context.
<p></dd>
<dt><B>*</B>
<dd>
These are now semantic errors because of precedence:
<p></dd>
<pre>
shift @list + 20;
$n = keys %map + 20;
</pre>
Because if that were to work, then this couldn't:
<p><pre>
sleep $dormancy + 20;
</pre>
<dt><B>*</B>
<dd>
<B>open FOO || die</B> is now incorrect. You need parens around the filehandle.
While temporarily supported, using such a construct will
generate a non-fatal (but non-suppressible) warning.
<p></dd>
<dt><B>*</B>
<dd>
The elements of argument lists for formats are now evaluated in list
context. This means you can interpolate list values now.
<p></dd>
<dt><B>*</B>
<dd>
You can't do a
<A HREF="perlfunc.html#perlfunc_151">goto</A>
into a block that is optimized away. Darn.
<p></dd>
<dt><B>*</B>
<dd>
It is no longer syntactically legal to use whitespace as the name
of a variable, or as a delimiter for any kind of quote construct.
Double darn.
<p></dd>
<dt><B>*</B>
<dd>
The caller() function now returns a false value in a scalar context if there
is no caller. This lets library files determine if they're being required.
<p></dd>
<dt><B>*</B>
<dd>
<B>m//g</B> now attaches its state to the searched string rather than the
regular expression.
<p></dd>
<dt><B>*</B>
<dd>
<A HREF="perlfunc.html#perlfunc_208">reverse</A>
is no longer allowed as the name of a sort subroutine.
<p></dd>
<dt><B>*</B>
<dd>
<B>taintperl</B> is no longer a separate executable. There is now a
<A HREF="perlrun.html#perlrun_358">-T</A>
switch to turn on tainting when it isn't turned on automatically.
<p></dd>
<dt><B>*</B>
<dd>
Double-quoted strings may no longer end with an unescaped <B>$</B> or <B>@</B>.
<p></dd>
<dt><B>*</B>
<dd>
The archaic <B>while/if</B> BLOCK BLOCK syntax is no longer supported.
<p></dd>
<dt><B>*</B>
<dd>
Negative array subscripts now count from the end of the array.
<p></dd>
<dt><B>*</B>
<dd>
The comma operator in a scalar context is now guaranteed to give a
scalar context to its arguments.
<p></dd>
<dt><B>*</B>
<dd>
The <B>**</B> operator now binds more tightly than unary minus.
It was documented to work this way before, but didn't.
<p></dd>
<dt><B>*</B>
<dd>
Setting <B>$#array</B> lower now discards array elements.
<p></dd>
<dt><B>*</B>
<dd>
delete() is not guaranteed to return the old value for tie()d arrays,
since this capability may be onerous for some modules to implement.